#include "map.h"
#include <QtGui>
#include <QPen>
#include<random>
#include <math.h>
#define N_grid 60//一条边上分割的格子总数
#define DIVIDER 10//格子的分辨率
QRect* getrect(int id)
{
    int c_x = id % N_grid;
    int c_z = id / N_grid;
    return new QRect(c_x*DIVIDER,c_z*DIVIDER,10,10);
}
int getid(QRect& rect)
{
    int c_x = rect.x() / DIVIDER;
    int c_z = rect.y() / DIVIDER;
    return c_z * N_grid + c_x;
}
Map::Map(QWidget *parent)
    : QWidget{parent}
{

    setAutoFillBackground(true);    	//对窗体背景色的设置
    setPalette(QPalette(Qt::white));
    pix =new QPixmap(size());           //此QPixmap对象用来准备随时接收绘制的内容
    pix->fill(Qt::white);            	//填充背景色为白色
    setMinimumSize(600,600);            //设置绘制区窗体的最小尺寸
    color=QColor(Qt::black);
    weight=1;
    style=Qt::SolidLine;
    pen =new QPen;	
    brush = new QBrush;//新建一个QPen对象

    //测试
    //block_type = Wall;
    use_type = Indiv_S;
    //初始化pen和brush的配置
    pen->setStyle((Qt::PenStyle)style);		//(a)
    pen->setWidth(weight);					//设置画笔的线宽值
    brush->setStyle(Qt::SolidPattern);
    
    //初始化边界墙的位置
    initWall();
    //初始化extra为false
    is_extra = false;
    //初始化上一次鼠标的位置
    lastPos = 0;
    //初始化临时区域
    tmp_A = QRect(0, 0, 0, 0);
    num_indiv = 10;
   

}
void Map::initWall()//初始化障碍物的位置
{
  
    //外墙1
    for (int i = 0; i < N_grid; i++)
    {
       wall_list.push_back(getrect(i));
    }
    //外墙2
    for (int i = 0; i < N_grid; i++)
    {
        wall_list.push_back(getrect(i * N_grid));
    }
    //外墙3
    for (int i = 0; i < N_grid; i++)
    {
 
        wall_list.push_back(getrect(i * N_grid + N_grid - 1));
    }
    //外墙4
    for (int i = 0; i < N_grid; i++)
    {
        if (i != int(N_grid / 2) - 1 && i != int(N_grid / 2) && i != int(N_grid / 2) + 1)
        {
            wall_list.push_back(getrect(i + N_grid * (N_grid - 1)));
        }
    }
}

void Map::mousePressEvent(QMouseEvent *e)
{
    startPos = e->pos();
    if (use_type == Wall_S)
    {
        if(is_extra)
            extra_wall_list.push_back(new QRect(startPos.x() / 10 * 10, startPos.y() / 10 * 10, 10, 10));
        else
            wall_list.push_back(new QRect(startPos.x() / 10*10, startPos.y() / 10*10, 10, 10));
        update();
    }
    else if (use_type == Indiv_S)
    {
        indiv_list.insert({new QPoint(startPos),rand()%3});
        update();
    }
}

void Map::mouseReleaseEvent(QMouseEvent *e )
{
    for (auto i : tmp_wall_list)
    {
        if(is_extra)
            extra_wall_list.push_back(i);
        else
            wall_list.push_back(i);
    }
    //在选中区域中随机生成指定个数的个体
    if (use_type == Indiv_M)
    {
        for (int i = 0; i < num_indiv; i++)
        {
           
            QPoint* indPos = new QPoint(tmp_A.x()+(rand()+i)%100/100.0*tmp_A.width(), tmp_A.y() + (rand()+i) % 100 / 100.0 * tmp_A.height());
            indiv_list.insert({ indPos,(rand()+i) % 3 });
        }
        
    }
    tmp_A = QRect(0, 0, 0, 0);
    tmp_wall_list.clear();
    endPos=e->pos();
    update();
}
void Map::mouseMoveEvent(QMouseEvent *e)
{
    if (use_type == Wall_M)
    {
        //如果还是在同一个点，就退出
        int currentPos = e->pos().x() / 10 + e->pos().y() / 10 * N_grid;
        if ( currentPos== lastPos)return;
        else
        {
            tmp_wall_list.clear();
            //lastPos = currentPos;
            //计算原点到当前点的距离
            float distance_l_c = std::sqrt(std::pow(e->pos().x()-startPos.x(),2)+ std::pow(e->pos().y() - startPos.y(), 2));
            float d_x = (e->pos().x() - startPos.x()) / distance_l_c;
            float d_y = (e->pos().y() - startPos.y()) / distance_l_c;
            //QPoint direction((e->pos().x() - startPos.x())/distance_l_c, (e->pos().y() - startPos.y()) / distance_l_c);//吐了这个东西会自动取整
            int iters = int(distance_l_c / DIVIDER) + 1;
            //int iters = 100;
            float step = distance_l_c / iters;
            for (int i = 0; i <= iters; i++)
            {
                QPoint delta(d_x*step*i,d_y*step*i);
                auto stepPos = startPos + delta;
                tmp_wall_list.push_back(new QRect(stepPos.x() / 10 * 10, stepPos.y() / 10 * 10, 10, 10));

            }
               
        }
       
    }
    else if (use_type == Indiv_M)
    {
        tmp_A = QRect(startPos,e->pos());
    }
    update();						//重绘绘制区窗体
}
void Map::draw()
{
   //不画了
}
void Map::paintEvent(QPaintEvent *)
{
    QPainter p(pix);						//新建一个QPainter对象
    						//设置QPainter对象的画笔
    					//设置QPainter对象的画刷
    //画多个体的范围
    pen->setWidth(0);
    pen->setColor(QColor(0xf5deb3));
    p.setPen(*pen);
    brush->setColor(QColor(0xf5deb366));
    p.setBrush(*brush);
    p.drawRect(tmp_A);
    //画临时墙
    if (is_extra)
    {
        pen->setWidth(0);
        pen->setColor(QColor(0xf5deb3));
        p.setPen(*pen);
        brush->setColor(QColor(0xf5deb3));
        p.setBrush(*brush);
    }
    else
    {
        pen->setWidth(0);
        pen->setColor(QColor(Qt::gray));
        p.setPen(*pen);
        brush->setColor(QColor(Qt::gray));
        p.setBrush(*brush);
    }
    for (auto i : tmp_wall_list)
    {
        p.drawRect(*i);
    }
    //画墙
    pen->setWidth(0);
    pen->setColor(QColor(Qt::gray));
    p.setPen(*pen);
    brush->setColor(QColor(Qt::gray));
    p.setBrush(*brush);
    for (auto i : wall_list)
    {
        
        p.drawRect(*i);
    }
    //画extra墙
    pen->setWidth(0);
    pen->setColor(QColor(0xf5deb3));
    p.setPen(*pen);
    brush->setColor(QColor(0xf5deb3));
    p.setBrush(*brush);
    for (auto i : extra_wall_list)
    {

        p.drawRect(*i);
    }
    //画个体
    pen->setWidth(5);
    p.setPen(*pen);
    for (auto i : indiv_list)
    {
        if (i.second == 0)
        {
            pen->setColor(QColor(Qt::blue));
            p.setPen(*pen);
            brush->setColor(QColor(Qt::blue));
            p.setBrush(*brush);
            p.drawPoints(i.first, 1);
        }
        else if (i.second == 1)
        {
            pen->setColor(QColor(Qt::red));
            p.setPen(*pen);
            brush->setColor(QColor(Qt::red));
            p.setBrush(*brush);
            p.drawPoints(i.first, 1);
        }
        else
        {
            pen->setColor(QColor(Qt::green));
            p.setPen(*pen);
            brush->setColor(QColor(Qt::green));
            p.setBrush(*brush);
            p.drawPoints(i.first, 1);
        }
    }


    QPainter painter(this);
    painter.drawPixmap(QPoint(0,0),*pix);
    pix->fill(Qt::white);
}
void Map::resizeEvent(QResizeEvent *event)
{
    if(height()>pix->height()||width()>pix->width())	//(a)
    {
        QPixmap *newPix = new QPixmap(size());	//创建一个新的QPixmap对象
        newPix->fill(Qt::white);                //填充新QPixmap对象newPix的颜色为白色背景色
        QPainter p(newPix);
        p.drawPixmap(QPoint(0,0),*pix);         //在newPix中绘制原pix中的内容
        pix = newPix;                           //将newPix赋值给pix作为新的绘制图形接收对象
    }
    QWidget::resizeEvent(event);                //完成其余的工作
}

